"""
chord.sync

This is the daemon that runs and periodically sends messages using chord.net to maintain the finger table.
"""
### Start of imports

# This line just better work...
from jackson import debug

# There's debug stuff for the rest
debug.pre_import(__name__)

debug.importing(__name__, 'choice from random', 3)
from random import choice

debug.importing(__name__, 'settings from django.conf', 2)
from django.conf import settings

debug.importing(__name__, 'core, net, db from jackson.chord')
from jackson.chord import core, net, db

debug.post_import(__name__)

### End of imports

def fix_fingers():
    """ Implements chord fix_fingers routine, taken from the Chord paper.
    @author: ep
    @rtype: None
    """
    context = [__name__, 'fix_finger()']
    debug.enter(context, None, 3)
    fix_one_finger(choice(range(2, settings.M + 1)))
    debug.leave(context, None, 3)

def fix_one_finger(k):
    """ Updates the value of finger k with the result of a fresh call to core.find_successor
    @author: ep
    @rtype: None
    """
    context = [__name__, 'fix_one_finger()']
    debug.enter(context, { 'k' : k }, 3)
    debug.comment(context, 'Fixing finger ' + str(k), 4)
    debug.comment(context, 'Looking up my key', 4)
    # Lookup my key
    my_key = db.get_me().key
    
    # Compute the k-th finger-key
    #@note: the offset of the k-th key is 2**(k-1)
    kth_key = core.get_key_plus_offset(my_key, 2**(k-1))
    debug.comment(context, 'Finger ' + str(k) + ' is successor(' + kth_key + ')', 4)

    # Find the successor of the k-th key
    succ_k = core.find_successor(kth_key)
    debug.comment(context, 'Finger ' + str(k) + ' is ' + str(succ_k), 4)
    
    # Update finger k
    core.set_finger(k, succ_k)
    debug.leave(context, None, 3)

def notify(pot_pred):
    """ Implements chord notify routine, taken from the Chord paper.
    @deprecated: Appears to be no use for this function. Probably will be removed.
    @author: ep
    @rtype: None
    """
    # Collect some info
    me = db.get_me()
    pred = core.get_predecessor()
    
    # Check if pot_pred could be this server's predecessor
    if core.key_in_range(pot_pred.key, pred.key, me.key):
        core.update_predecessor(pot_pred)

